package installer

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"go.uber.org/zap"
)

// extractTarFile 解压tar文件
// 示例值: tarPath="/tmp/ssh-upgrade/openssh-9.7p1.tar.gz"
func (i *Installer) extractTarFile(tarPath string) (string, error) {
	zap.L().Info("解压文件", zap.String("tarPath", tarPath))

	// 创建临时解压目录
	extractDir := filepath.Join("/tmp", "openssh-extract")
	if err := os.MkdirAll(extractDir, 0755); err != nil {
		return "", fmt.Errorf("创建解压目录失败: %v", err)
	}

	// 解压tar.gz文件
	cmd := exec.Command("tar", "-xzf", tarPath, "-C", extractDir)
	if err := cmd.Run(); err != nil {
		return "", fmt.Errorf("解压失败: %v", err)
	}

	// 查找解压后的目录
	entries, err := os.ReadDir(extractDir)
	if err != nil {
		return "", fmt.Errorf("读取解压目录失败: %v", err)
	}

	for _, entry := range entries {
		if entry.IsDir() && strings.HasPrefix(entry.Name(), "openssh-") {
			sourceDir := filepath.Join(extractDir, entry.Name())
			zap.L().Info("找到源码目录", zap.String("sourceDir", sourceDir))
			return sourceDir, nil
		}
	}

	return "", fmt.Errorf("未找到openssh源码目录")
}

// compileAndInstall 编译和安装
// 示例值: sourceDir="/tmp/openssh-extract/openssh-9.7p1"
func (i *Installer) compileAndInstall(sourceDir string) error {
	zap.L().Info("编译安装OpenSSH", zap.String("sourceDir", sourceDir))

	// 切换到源码目录
	if err := os.Chdir(sourceDir); err != nil {
		return fmt.Errorf("切换目录失败: %v", err)
	}

	// 配置编译选项
	configureCmd := exec.Command("./configure",
		"--prefix="+i.installDir,
		"--sysconfdir=/etc/ssh",
		"--with-pam",
		"--with-zlib",
		"--with-ssl-dir=/usr",
		"--with-md5-passwords",
		"--with-privsep-path=/var/empty/sshd",
	)

	configureCmd.Stdout = os.Stdout
	configureCmd.Stderr = os.Stderr

	if err := configureCmd.Run(); err != nil {
		return fmt.Errorf("配置失败: %v", err)
	}

	// 编译
	makeCmd := exec.Command("make")
	makeCmd.Stdout = os.Stdout
	makeCmd.Stderr = os.Stderr

	if err := makeCmd.Run(); err != nil {
		return fmt.Errorf("编译失败: %v", err)
	}

	// 安装
	makeInstallCmd := exec.Command("make", "install")
	makeInstallCmd.Stdout = os.Stdout
	makeInstallCmd.Stderr = os.Stderr

	if err := makeInstallCmd.Run(); err != nil {
		return fmt.Errorf("安装失败: %v", err)
	}

	zap.L().Info("OpenSSH编译安装完成", zap.String("installDir", i.installDir))
	return nil
}